
from flask import Blueprint
from flask import request
from flask import render_template
from flask import flash
from flask import redirect
from flask import url_for

from app import db
from app.security import permission

from app.wtforms.permiso_forms import PermisoBuscar
from app.wtforms.permiso_forms import PermisoEditable
from app.wtforms.permiso_forms import PermisoNoEditable

from app.models.permiso import Permiso
from app.models.entidad import Entidad
from app.models.rol import Rol


mod = Blueprint('permisos', __name__, url_prefix='/permisos')

#Lista de los nombre de los permisos por defecto del sistema
permisos_por_defecto = ['CREAR_USUARIO','MODIFICAR_USUARIO','DESACTIVAR_USUARIO','VER_USUARIO','CREAR_ROL','MODIFICAR_ROL','ELIMINAR_ROL','VER_ROL','CREAR_PERMISO','ELIMINAR_PERMISO','ACTIVAR_USUARIO']

@mod.route('/administracion/', methods=['GET', 'POST'])
@permission('ADMINISTRACION_PERMISOS')
def administracion_permiso():
       
    """
    Muestra en pantalla los permisos que existen en la base de datos.
    Si no recibe algun filtro como parametro, lista todos los permisos.
    Si recibe algun filtro, muestra los permisos que cumplen con el filtro indicado
    """
    # Obtenemos el formulario
    form =  PermisoBuscar(request.form)    
      
    # Obtenemos el filtro
    nombreFilter = form.nombre.data
    entidadFilter = form.entidad.data
    
    if(nombreFilter == None):
        nombreFilter = '' 
    if(entidadFilter == None):
        entidadFilter = ''  
    
    # Recuperamor de la base de datos lo permisos que coinciden con el filtro
    #===========================================================================
    # permisos = Permiso.query.filter(Permiso.nombre.like( '%'+nombreFilter+'%' )).join(Entidad).filter(Entidad.nombre.like('%' + entidadFilter + '%'))
    #===========================================================================
    permisos = Permiso.query.filter(Permiso.nombre.like( '%'+nombreFilter+'%' ))
    permisos = permisos.all()    
             
        
    return render_template('permiso/administracion_permiso.html', form = form, permisos = permisos)




@mod.route('/crear/', methods=['GET', 'POST'])
@permission('CREAR_PERMISO')
def crear_permiso():
    """
    Muestra en pantalla el formulario de creacion de permisos, valida los datos ingresados por
    el usuario, hace las validaciones de que el nombre del nuevo permiso no exista en el
    sistema y se hayan ingresado los datos obligatorios. Luego almacena en base de datos
    """
    
    # Obtenemos el formulario
    form = PermisoEditable(request.form)
  
    choicesEntidades = []
    choicesPermisos = [('1', 'VER'), ('2', 'MODIFICAR'), ('3','ELIMINAR')]
    
    # Obtenemos todas las entidades existentes en la base de datos
    #entidades = Entidad.query.filter(~(Entidad.id.in_(db.session.query(Permiso.entidad_id).filter().all())))
    entidades = Entidad.query.filter()
    entidades.all()
        
    
    for entidad in entidades:
        choicesEntidades.append((str(entidad.id), entidad.nombre))
  
    form.entidad.choices = choicesEntidades
    form.nombre.choices = choicesPermisos
   
    if form.validate_on_submit():
        
        cont = 0
        
        descripcion = form.descripcion.data
        posicion = int(form.nombre.data)-1
    
        entidad = Entidad.query.get(int(form.entidad.data))
        
        permisos = Permiso.query.filter_by(entidad_id=entidad.id)
        permisos = permisos.all()
        
        for permiso in permisos:
            if permiso.nombre == choicesPermisos[posicion][1]:
                cont = cont + 1
        
        if cont == 0:
            permiso = Permiso(choicesPermisos[posicion][1], descripcion,entidad) 
            db.session.add(permiso)
            db.session.commit()
        
            flash('El permiso ha sido registrado con exito')
            return redirect(url_for('permisos.administracion_permiso'))

        else:
            flash('El permiso ya existe')
            return redirect(url_for('permisos.crear_permiso'))
            

    return render_template("permiso/crear_permiso.html", form=form)


@mod.route('/consultar/<permiso>/', methods=['GET', 'POST'])
@permission('VER_PERMISO')
def consultar_permiso(permiso):
    """
    Muestra en pantalla el formulario de consulta de permisos, muestra todos los datos del
    permiso seleccionado
    :param permiso:
    id del permiso que se desea consultar
    """
    
    # Obtenemos el formulario
    form = PermisoNoEditable(request.form)
    
    #Obtenemos el permiso seleccionado
    permiso_seleccionado = Permiso.query.filter_by(id=permiso).first()
    
    
                                       
    
        
    if form.validate_on_submit():
        
        #Cuando el usuario presiona aceptar, redirigimos a la pagina de administracion de permisos
        return redirect(url_for('permisos.administracion_permiso'))
    
    
    
    #Mostramos los datos actuales del permiso seleccionado
    form.nombre.data = permiso_seleccionado.nombre
    form.descripcion.data = permiso_seleccionado.descripcion
    if permiso_seleccionado.entidad != None:
        form.entidad.data = permiso_seleccionado.entidad.nombre
    else:
        form.entidad.data = "no posee entidad asociada"
    
    return render_template('permiso/consultar_permiso.html', form = form, 
                           permiso_seleccionado=permiso_seleccionado)
    


@mod.route('/modificar/<permiso>/', methods=['GET', 'POST'])
@permission('MODIFICAR_PERMISO')
def modificar_permiso(permiso):
    """
    Muestra en pantalla el formulario de modificacion de permisos
    :param permiso:
    id del permiso seleccionado
    """
    
    #Obtenemos el permiso seleccionado
    permiso_seleccionado = Permiso.query.filter_by(id=permiso).first()
    
    if permiso_seleccionado.nombre in permisos_por_defecto:
         
        # Si el permiso seleccionado es un permiso por defecto no permitimos la modificacion
        flash('No se puede modificar el permiso por defecto %s ' % permiso_seleccionado.nombre,
               'error-message')
        return redirect(url_for('permisos.administracion_permiso', permiso=permiso))
     
    else:
    
        # Obtenemos el formulario
        form = PermisoNoEditable(request.form)
        
        
        # Validamos los datos ingresados al formulario
        if form.validate_on_submit():
            # Realizamos los cambios en la descripcion del permiso
            permiso_seleccionado.setDescripcion(form.descripcion.data)
            
            
            #Almacenamos el permiso modificado en la base de datos
            db.session.add(permiso_seleccionado)
            db.session.commit()
                    
            # Retornamos a la pagina de administracion de roles
            flash('El permiso ha sido registrado con exito')
            return redirect(url_for('permisos.administracion_permiso'))
        
                
        # Mostramos en el formulario los datos actuales del permiso seleccionado
        form.nombre.data = permiso_seleccionado.nombre
        form.descripcion.data = permiso_seleccionado.descripcion
        form.entidad.data = permiso_seleccionado.entidad.nombre
                       
        return render_template('permiso/modificar_permiso.html', form = form, 
                               permiso_seleccionado=permiso_seleccionado)


@mod.route('/eliminar/<permiso>/', methods=['GET', 'POST'])
@permission('ELIMINAR_PERMISO')
def eliminar_permiso(permiso):
    """
    Muestra en pantalla el formulario de eliminacion de permisos.
    :param permiso:
    id del permiso que se desea eliminar
    """
    
    #Obtenemos el permiso seleccionado
    permiso_seleccionado = Permiso.query.filter_by(id=permiso).first()
    
    if permiso_seleccionado.nombre in permisos_por_defecto:
        
        # Si el permiso seleccionado es un permiso por defecto no permitimos la eliminacion
        flash('No se puede elimninar el permiso por defecto %s' % permiso_seleccionado.nombre,
               'error-message')
        return redirect(url_for('permisos.administracion_permiso', permiso=permiso))
    
    else:
         
        # Obtenemos todos los roles de la base de datos
        roles = Rol.query.all()
    
        for rol in roles:
            for per in rol.permiso: 
                if permiso_seleccionado.nombre in per.nombre: 
                    #Si el permiso seleccionado se encuentra relacionado 
                    #con algun rol no permitimos la eliminacion
                    flash('No se puede elimninar el permiso, se encuentra relacionado con un rol %s' % rol.nombre,
                           'error-message')
                    return redirect(url_for('permisos.administracion_permiso', permiso=permiso))
      
        
        # Obtenemos el formulario
        form = PermisoNoEditable(request.form)
                
        # Mostramos el nombre del permiso
        form.nombre.data = permiso_seleccionado.nombre
        # Mostramos la descripcion del permiso
        form.descripcion.data = permiso_seleccionado.descripcion
       
                   
        # Borramos de la base de datos el permiso
        db.session.delete(permiso_seleccionado)
        db.session.commit()
           
        flash('El permiso ha sido eliminado') 
        # Redirigimos a la pagina de administracion de permisos
        return redirect(url_for('permisos.administracion_permiso'))
      
    
        
    
    
    
    
    
    
    
        